using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Options;
using RAGApp.Api.Configurations;
using RAGApp.Api.Services.Interfaces;

namespace RAGApp.Api.Services;

public class XunfeiEmbeddingService : IEmbeddingService
{
    private readonly XunfeiConfig _config;
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<XunfeiEmbeddingService> _logger;

    public XunfeiEmbeddingService(
        IOptions<XunfeiConfig> config,
        IHttpClientFactory httpClientFactory,
        ILogger<XunfeiEmbeddingService> logger)
    {
        _config = config.Value;
        _httpClientFactory = httpClientFactory;
        _logger = logger;
    }

    public async Task<float[]> GenerateEmbeddingAsync(string text)
    {
        var texts = new List<string> { text };
        var embeddings = await GenerateEmbeddingsAsync(texts);
        return embeddings.FirstOrDefault() ?? Array.Empty<float>();
    }

    public async Task<List<float[]>> GenerateEmbeddingsAsync(List<string> texts)
    {
        try
        {
            var client = _httpClientFactory.CreateClient();
            var date = DateTime.UtcNow.ToString("r");
            var host = _config.ApiDomain;
            var path = _config.ChatPath; // 使用Chat API路径，因为向量生成是通过大模型API提供的

            var messages = new List<object>();
            foreach (var text in texts)
            {
                messages.Add(new
                {
                    role = "user",
                    content = text,
                    function = "embedding" // 指定使用embedding功能
                });
            }

            var requestBody = new
            {
                header = new
                {
                    app_id = _config.AppId
                },
                parameter = new
                {
                    chat = new
                    {
                        domain = "general",
                        temperature = 0.0,
                        max_tokens = 2048
                    }
                },
                payload = new
                {
                    message = new
                    {
                        text = messages
                    }
                }
            };

            var jsonBody = JsonSerializer.Serialize(requestBody);
            var signature = GenerateSignature("POST", host, path, date, jsonBody);

            var request = new HttpRequestMessage(HttpMethod.Post, $"https://{host}{path}")
            {
                Content = new StringContent(jsonBody, Encoding.UTF8, "application/json")
            };

            request.Headers.Add("Host", host);
            request.Headers.Add("Date", date);
            request.Headers.Add("Authorization", signature);

            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode();

            var jsonResponse = await response.Content.ReadAsStringAsync();
            var responseObj = JsonSerializer.Deserialize<XunfeiEmbeddingResponse>(jsonResponse);

            if (responseObj?.Header?.Code != 0)
            {
                throw new Exception($"讯飞API返回错误：{responseObj?.Header?.Message}");
            }

            return responseObj?.Payload?.Embeddings ?? new List<float[]>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "生成向量时发生错误");
            throw;
        }
    }

    private string GenerateSignature(string method, string host, string path, string date, string body)
    {
        var stringToSign = $"{method}\n{host}\n{path}\n{date}\n{body}";
        var secretBytes = Encoding.UTF8.GetBytes(_config.ApiSecret);
        
        using var hmac = new HMACSHA256(secretBytes);
        var signatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
        var signature = Convert.ToBase64String(signatureBytes);

        return $"api_key=\"{_config.ApiKey}\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"{signature}\"";
    }
}

public class XunfeiEmbeddingResponse
{
    public ResponseHeader? Header { get; set; }
    public EmbeddingPayload? Payload { get; set; }

    public class ResponseHeader
    {
        public int Code { get; set; }
        public string? Message { get; set; }
        public string? Sid { get; set; }
    }

    public class EmbeddingPayload
    {
        public List<float[]>? Embeddings { get; set; }
    }
} 